/**
 * 
 */
package tv.geir.slackspace.analyzer;

import java.util.Set;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;

/**
 * @author Geir Gullestad Pettersen
 *
 */
public class MethodVisitorAnalyzer implements MethodVisitor {

	/**
	 * 
	 */
	private static Log log = LogFactory.getLog(MethodVisitorAnalyzer.class);
	
	/**
	 * 
	 */
	private Set<String>dependencies;
	
	
	
	public MethodVisitorAnalyzer(Set<String> dependencies) {
		super();
		this.dependencies = dependencies;
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitAnnotation(java.lang.String, boolean)
	 */
	public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
		// TODO Auto-generated method stub
	
		return null;
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitAnnotationDefault()
	 */
	public AnnotationVisitor visitAnnotationDefault() {
		// TODO Auto-generated method stub
		
		return null;
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitAttribute(org.objectweb.asm.Attribute)
	 */
	public void visitAttribute(Attribute arg0) {
		// TODO Auto-generated method stub
		log.info("visitAttribute(): " + arg0.type );

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitCode()
	 */
	public void visitCode() {
		// TODO Auto-generated method stub
		log.info("visitCode()");
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitEnd()
	 */
	public void visitEnd() {
		// TODO Auto-generated method stub
		log.info("visitEnd()");
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitFieldInsn(int, java.lang.String, java.lang.String, java.lang.String)
	 */
	public void visitFieldInsn(int arg0, String arg1, String arg2, String arg3) {
		log.info( new ToStringBuilder("visitFieldIsn()").append("arg0", arg0).append("arg1").append("arg2", arg2).append("arg3", arg3).toString() );
		
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitIincInsn(int, int)
	 */
	public void visitIincInsn(int arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitInsn(int)
	 */
	public void visitInsn(int arg0) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitIntInsn(int, int)
	 */
	public void visitIntInsn(int arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitJumpInsn(int, org.objectweb.asm.Label)
	 */
	public void visitJumpInsn(int arg0, Label arg1) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitLabel(org.objectweb.asm.Label)
	 */
	public void visitLabel(Label arg0) {
		// TODO Auto-generated method stub
		log.info("visitLabel() " + arg0 );
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitLdcInsn(java.lang.Object)
	 */
	public void visitLdcInsn(Object arg0) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitLineNumber(int, org.objectweb.asm.Label)
	 */
	public void visitLineNumber(int arg0, Label arg1) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitLocalVariable(java.lang.String, java.lang.String, java.lang.String, org.objectweb.asm.Label, org.objectweb.asm.Label, int)
	 */
	public void visitLocalVariable(String arg0, String arg1, String arg2,
			Label arg3, Label arg4, int arg5) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitLookupSwitchInsn(org.objectweb.asm.Label, int[], org.objectweb.asm.Label[])
	 */
	public void visitLookupSwitchInsn(Label arg0, int[] arg1, Label[] arg2) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitMaxs(int, int)
	 */
	public void visitMaxs(int arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitMethodInsn(int, java.lang.String, java.lang.String, java.lang.String)
	 */
	public void visitMethodInsn(int arg0, String className, String arg2, String arg3) {
		
		
		addClassName(className);
		Set<String> classes = utils.getClassNamesFromSignature(arg3);
		for( String cname : classes ) {
			addClassName( cname );
		}
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitMultiANewArrayInsn(java.lang.String, int)
	 */
	public void visitMultiANewArrayInsn(String arg0, int arg1) {
		// TODO Auto-generated method stub
		log.info( "visitMultiANewArrayInsn() "+ arg0 +", " + arg1 );
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitParameterAnnotation(int, java.lang.String, boolean)
	 */
	public AnnotationVisitor visitParameterAnnotation(int arg0, String arg1,
			boolean arg2) {
		log.info( "visitParameterAnnotation() " + arg0 +", " + arg1 );

		return null;
	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitTableSwitchInsn(int, int, org.objectweb.asm.Label, org.objectweb.asm.Label[])
	 */
	public void visitTableSwitchInsn(int arg0, int arg1, Label arg2,
			Label[] arg3) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitTryCatchBlock(org.objectweb.asm.Label, org.objectweb.asm.Label, org.objectweb.asm.Label, java.lang.String)
	 */
	public void visitTryCatchBlock(Label arg0, Label arg1, Label arg2,
			String arg3) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitTypeInsn(int, java.lang.String)
	 */
	public void visitTypeInsn(int arg0, String arg1) {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.objectweb.asm.MethodVisitor#visitVarInsn(int, int)
	 */
	public void visitVarInsn(int arg0, int arg1) {
		// TODO Auto-generated method stub

	}

	void addClassName( String name ) {
		dependencies.add( utils.classUrlToQualifiedClassName(name));
		if( log.isDebugEnabled() ) {
			log.debug( "Class found in bytecode and added to dependency list: " + name );
		}
	}
	
	private ClassNameUtils utils = new ClassNameUtils();
}
